import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sqflite/sqflite.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'dart:io';
import 'package:path/path.dart';
import '../types/app_types.dart';

/**
 * 本地存储服务
 * 负责数据的本地持久化存储
 */
class StorageService {
  static Database? _database;
  static SharedPreferences? _prefs;

  /**
   * 初始化存储服务
   */
  static Future<void> initialize() async {
    // 在桌面平台上初始化 sqflite_ffi
    if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
      sqfliteFfiInit();
      databaseFactory = databaseFactoryFfi;
    }
    
    _prefs = await SharedPreferences.getInstance();
    await _initDatabase();
  }

  /**
   * 初始化数据库
   */
  static Future<void> _initDatabase() async {
    final databasesPath = await getDatabasesPath();
    final path = join(databasesPath, 'linkbook.db');

    _database = await openDatabase(
      path,
      version: 2,
      onCreate: (db, version) async {
        await _createTables(db);
      },
      onUpgrade: (db, oldVersion, newVersion) async {
        if (oldVersion < 2) {
          await _upgradeToV2(db);
        }
      },
    );
  }

  /**
   * 创建数据表
   */
  static Future<void> _createTables(Database db) async {
    // 创建文件夹表
    await db.execute('''
      CREATE TABLE folders (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        count INTEGER DEFAULT 0,
        is_default INTEGER DEFAULT 0,
        is_shared INTEGER DEFAULT 0,
        parent_id INTEGER,
        sort_order INTEGER DEFAULT 0,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        sync_status TEXT DEFAULT 'local',
        server_id TEXT,
        share_link TEXT,
        share_password TEXT
      )
    ''');

    // 创建笔记表
    await db.execute('''
      CREATE TABLE notes (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT NOT NULL,
        content TEXT NOT NULL,
        folder_id INTEGER,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        sync_status TEXT DEFAULT 'local',
        server_id TEXT,
        tags TEXT,
        is_shared INTEGER DEFAULT 0,
        share_link TEXT,
        share_password TEXT,
        FOREIGN KEY (folder_id) REFERENCES folders (id)
      )
    ''');

    // 插入默认文件夹
    await _insertDefaultFolders(db);
  }

  /**
   * 升级到版本2
   */
  static Future<void> _upgradeToV2(Database db) async {
    // 添加新字段
    await db.execute('ALTER TABLE folders ADD COLUMN share_link TEXT');
    await db.execute('ALTER TABLE folders ADD COLUMN share_password TEXT');
    await db.execute('ALTER TABLE notes ADD COLUMN tags TEXT');
    await db.execute('ALTER TABLE notes ADD COLUMN is_shared INTEGER DEFAULT 0');
    await db.execute('ALTER TABLE notes ADD COLUMN share_link TEXT');
    await db.execute('ALTER TABLE notes ADD COLUMN share_password TEXT');
  }

  /**
   * 插入默认文件夹
   */
  static Future<void> _insertDefaultFolders(Database db) async {
    final now = DateTime.now().toIso8601String();
    
    await db.insert('folders', {
      'id': 1,
      'name': '全部笔记',
      'is_default': 1,
      'created_at': now,
      'updated_at': now,
    });

    await db.insert('folders', {
      'id': 2,
      'name': '未分类',
      'is_default': 1,
      'created_at': now,
      'updated_at': now,
    });
  }

  /**
   * 获取数据库实例
   */
  Database get database {
    if (_database == null) {
      throw Exception('Database not initialized. Call StorageService.initialize() first.');
    }
    return _database!;
  }

  /**
   * 获取 SharedPreferences 实例
   */
  SharedPreferences get prefs {
    if (_prefs == null) {
      throw Exception('SharedPreferences not initialized. Call StorageService.initialize() first.');
    }
    return _prefs!;
  }

  // ========== 文件夹相关操作 ==========

  /**
   * 获取所有文件夹
   */
  Future<List<Folder>> getFolders() async {
    final List<Map<String, dynamic>> maps = await database.query(
      'folders',
      orderBy: 'sort_order ASC, created_at ASC',
    );

    return maps.map((map) => _mapToFolder(map)).toList();
  }

  /**
   * 根据ID获取文件夹
   */
  Future<Folder?> getFolderById(int id) async {
    final List<Map<String, dynamic>> maps = await database.query(
      'folders',
      where: 'id = ?',
      whereArgs: [id],
    );

    if (maps.isEmpty) return null;
    return _mapToFolder(maps.first);
  }

  /**
   * 创建文件夹
   */
  Future<Folder> createFolder(Folder folder) async {
    final now = DateTime.now();
    final id = await database.insert('folders', {
      'name': folder.name,
      'count': folder.count,
      'is_default': folder.isDefault ? 1 : 0,
      'is_shared': folder.isShared ? 1 : 0,
      'parent_id': folder.parentId,
      'sort_order': folder.sortOrder,
      'created_at': now.toIso8601String(),
      'updated_at': now.toIso8601String(),
      'sync_status': folder.syncStatus.name,
      'server_id': folder.serverId,
      'share_link': folder.shareLink,
      'share_password': folder.sharePassword,
    });

    return folder.copyWith(
      id: id,
      createdAt: now,
      updatedAt: now,
    );
  }

  /**
   * 更新文件夹
   */
  Future<Folder> updateFolder(Folder folder) async {
    final now = DateTime.now();
    await database.update(
      'folders',
      {
        'name': folder.name,
        'count': folder.count,
        'is_default': folder.isDefault ? 1 : 0,
        'is_shared': folder.isShared ? 1 : 0,
        'parent_id': folder.parentId,
        'sort_order': folder.sortOrder,
        'updated_at': now.toIso8601String(),
        'sync_status': folder.syncStatus.name,
        'server_id': folder.serverId,
        'share_link': folder.shareLink,
        'share_password': folder.sharePassword,
      },
      where: 'id = ?',
      whereArgs: [folder.id],
    );

    return folder.copyWith(updatedAt: now);
  }

  /**
   * 删除文件夹
   */
  Future<void> deleteFolder(int id) async {
    // 将该文件夹下的笔记移动到"未分类"
    await database.update(
      'notes',
      {'folder_id': 2}, // 2 是"未分类"文件夹的ID
      where: 'folder_id = ?',
      whereArgs: [id],
    );

    // 删除文件夹
    await database.delete(
      'folders',
      where: 'id = ?',
      whereArgs: [id],
    );
  }

  // ========== 笔记相关操作 ==========

  /**
   * 获取所有笔记
   */
  Future<List<Note>> getNotes() async {
    final List<Map<String, dynamic>> maps = await database.query(
      'notes',
      orderBy: 'updated_at DESC',
    );

    return maps.map((map) => _mapToNote(map)).toList();
  }

  /**
   * 根据文件夹ID获取笔记
   */
  Future<List<Note>> getNotesByFolderId(int folderId) async {
    final List<Map<String, dynamic>> maps = await database.query(
      'notes',
      where: 'folder_id = ?',
      whereArgs: [folderId],
      orderBy: 'updated_at DESC',
    );

    return maps.map((map) => _mapToNote(map)).toList();
  }

  /**
   * 根据ID获取笔记
   */
  Future<Note?> getNoteById(int id) async {
    final List<Map<String, dynamic>> maps = await database.query(
      'notes',
      where: 'id = ?',
      whereArgs: [id],
    );

    if (maps.isEmpty) return null;
    return _mapToNote(maps.first);
  }

  /**
   * 搜索笔记
   */
  Future<List<Note>> searchNotes(String query) async {
    final List<Map<String, dynamic>> maps = await database.query(
      'notes',
      where: 'title LIKE ? OR content LIKE ?',
      whereArgs: ['%$query%', '%$query%'],
      orderBy: 'updated_at DESC',
    );

    return maps.map((map) => _mapToNote(map)).toList();
  }

  /**
   * 创建笔记
   */
  Future<Note> createNote(Note note) async {
    final now = DateTime.now();
    final id = await database.insert('notes', {
      'title': note.title,
      'content': note.content,
      'folder_id': note.folderId,
      'created_at': now.toIso8601String(),
      'updated_at': now.toIso8601String(),
      'sync_status': note.syncStatus.name,
      'server_id': note.serverId,
      'tags': jsonEncode(note.tags),
      'is_shared': note.isShared ? 1 : 0,
      'share_link': note.shareLink,
      'share_password': note.sharePassword,
    });

    return note.copyWith(
      id: id,
      createdAt: now,
      updatedAt: now,
    );
  }

  /**
   * 更新笔记
   */
  Future<Note> updateNote(Note note) async {
    final now = DateTime.now();
    await database.update(
      'notes',
      {
        'title': note.title,
        'content': note.content,
        'folder_id': note.folderId,
        'updated_at': now.toIso8601String(),
        'sync_status': note.syncStatus.name,
        'server_id': note.serverId,
        'tags': jsonEncode(note.tags),
        'is_shared': note.isShared ? 1 : 0,
        'share_link': note.shareLink,
        'share_password': note.sharePassword,
      },
      where: 'id = ?',
      whereArgs: [note.id],
    );

    return note.copyWith(updatedAt: now);
  }

  /**
   * 删除笔记
   */
  Future<void> deleteNote(int id) async {
    await database.delete(
      'notes',
      where: 'id = ?',
      whereArgs: [id],
    );
  }

  // ========== 设置相关操作 ==========

  /**
   * 保存设置
   */
  Future<void> saveSetting(String key, dynamic value) async {
    if (value is String) {
      await prefs.setString(key, value);
    } else if (value is int) {
      await prefs.setInt(key, value);
    } else if (value is double) {
      await prefs.setDouble(key, value);
    } else if (value is bool) {
      await prefs.setBool(key, value);
    } else if (value is List<String>) {
      await prefs.setStringList(key, value);
    } else {
      await prefs.setString(key, jsonEncode(value));
    }
  }

  /**
   * 获取设置
   */
  T? getSetting<T>(String key, {T? defaultValue}) {
    if (!prefs.containsKey(key)) return defaultValue;

    final value = prefs.get(key);
    if (value is T) return value;
    
    // 尝试从JSON解析
    if (value is String && T != String) {
      try {
        return jsonDecode(value) as T;
      } catch (e) {
        return defaultValue;
      }
    }

    return defaultValue;
  }

  /**
   * 删除设置
   */
  Future<void> removeSetting(String key) async {
    await prefs.remove(key);
  }

  /**
   * 清除所有设置
   */
  Future<void> clearSettings() async {
    await prefs.clear();
  }

  // ========== 辅助方法 ==========

  /**
   * 将数据库映射转换为文件夹对象
   */
  Folder _mapToFolder(Map<String, dynamic> map) {
    return Folder(
      id: map['id'] as int,
      name: map['name'] as String,
      count: map['count'] as int? ?? 0,
      isDefault: (map['is_default'] as int? ?? 0) == 1,
      isShared: (map['is_shared'] as int? ?? 0) == 1,
      parentId: map['parent_id'] as int?,
      sortOrder: map['sort_order'] as int? ?? 0,
      createdAt: DateTime.parse(map['created_at'] as String),
      updatedAt: DateTime.parse(map['updated_at'] as String),
      syncStatus: SyncStatus.values.firstWhere(
        (s) => s.name == (map['sync_status'] as String? ?? 'local'),
        orElse: () => SyncStatus.local,
      ),
      serverId: map['server_id'] as String?,
      shareLink: map['share_link'] as String?,
      sharePassword: map['share_password'] as String?,
    );
  }

  /**
   * 将数据库映射转换为笔记对象
   */
  Note _mapToNote(Map<String, dynamic> map) {
    List<String> tags = [];
    final tagsJson = map['tags'] as String?;
    if (tagsJson != null && tagsJson.isNotEmpty) {
      try {
        tags = List<String>.from(jsonDecode(tagsJson));
      } catch (e) {
        // 忽略解析错误
      }
    }

    return Note(
      id: map['id'] as int,
      title: map['title'] as String,
      content: map['content'] as String,
      folderId: map['folder_id'] as int?,
      createdAt: DateTime.parse(map['created_at'] as String),
      updatedAt: DateTime.parse(map['updated_at'] as String),
      syncStatus: SyncStatus.values.firstWhere(
        (s) => s.name == (map['sync_status'] as String? ?? 'local'),
        orElse: () => SyncStatus.local,
      ),
      serverId: map['server_id'] as String?,
      tags: tags,
      isShared: (map['is_shared'] as int? ?? 0) == 1,
      shareLink: map['share_link'] as String?,
      sharePassword: map['share_password'] as String?,
    );
  }

  /**
   * 关闭数据库连接
   */
  Future<void> close() async {
    await _database?.close();
    _database = null;
  }
}